package cn.lxh.template;


import cn.lxh.pojo.properties.WxPayProperties;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.profitsharing.ProfitsharingService;
import com.wechat.pay.java.service.profitsharing.model.*;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class WxPayTemplate {

    private WxPayProperties properties;
    private Config config;

    public WxPayTemplate(WxPayProperties properties, Config config){
        this.properties = properties;
        this.config = config;
    }

    //微信支付
    public PrepayWithRequestPaymentResponse createPreOrder(String desc, String payOrderNo, String openId, BigDecimal price){

        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();

        // 跟之前下单示例一样，填充预下单参数
        PrepayRequest request = new PrepayRequest();

        Amount amount = new Amount();
        amount.setTotal(1);//1分钱
        //int value = price.multiply(new BigDecimal("100")).intValue();
        request.setAmount(amount);
        request.setAppid(properties.getAppId());
        request.setMchid(properties.getMerchantId());
        request.setDescription(desc);
        request.setNotifyUrl(properties.getNotifyUrl());
        request.setOutTradeNo(payOrderNo);
        Payer payer = new Payer();
        payer.setOpenid(openId);
        request.setPayer(payer);

        // response包含了调起支付所需的所有参数，可直接用于前端调起支付
        PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
        return response;
    }

    //异步结果验签
    public Transaction checkSign(HttpServletRequest request){
        //* 1.获取请求体中的body
        //ServletInputStream inputStream = request.getInputStream();
        try {
            //获取Body
            BufferedReader reader = request.getReader();
            StringBuilder body = new StringBuilder();
            String line = null;
            while((line = reader.readLine()) != null){
                body.append(line);
            }
            //* 2.获取请求头中的数据
            String signature = request.getHeader("Wechatpay-Signature");
            String serial = request.getHeader("Wechatpay-Serial");
            String nonce = request.getHeader("Wechatpay-Nonce");
            String timestamp = request.getHeader("Wechatpay-Timestamp");

            //* 3.构建：RequestParam 参数对象，构建：NotificationParser 解析器

            RequestParam requestParam = new RequestParam.Builder()
                    .serialNumber(serial)
                    .nonce(nonce)
                    .signature(signature)
                    .timestamp(timestamp)
                    .body(body.toString())
                    .build();

            //* 4.解析：验签、解密并转换成 Transaction
            NotificationParser parser = new NotificationParser((NotificationConfig)config);
            Transaction transaction = parser.parse(requestParam, Transaction.class);
            log.info("支付结果验签 {}",transaction);
            return transaction;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void closeWxPreOrder(String outTradeNo){
        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
        CloseOrderRequest request = new CloseOrderRequest();
        request.setMchid(properties.getMerchantId());
        request.setOutTradeNo(outTradeNo);
        service.closeOrder(request);
    }

    //添加分账接收方
    public void addProfitSharingReceiver(String openId){
        //1.构建分账服务
        ProfitsharingService profitsharingService = new ProfitsharingService.Builder().config(config).build();
        AddReceiverRequest addReceiverRequest = new AddReceiverRequest();
        //小程序ID
        addReceiverRequest.setAppid(properties.getAppId());
        //分账人的OpenId
        addReceiverRequest.setAccount(openId);
        //类型，合作伙伴
        addReceiverRequest.setRelationType(ReceiverRelationType.PARTNER);
        //类型：个人
        addReceiverRequest.setType(ReceiverType.PERSONAL_OPENID);
        AddReceiverResponse addReceiverResponse = profitsharingService.addReceiver(addReceiverRequest);
        log.info("添加分账接收人 {}" ,addReceiverResponse);
    }

    /**
     * //执行分账
     * @param openId:收款人的微信ID
     * @param transactionId ：微信支付单的单号 - 支付结果后能拿到
     * @param outOrderNo ：支付单号
     */
    public boolean doProfitSharing(String openId,String transactionId,String outOrderNo,BigDecimal amount){
        addProfitSharingReceiver(openId);
        //执行分账
        ProfitsharingService profitsharingService = new ProfitsharingService.Builder().config(config).build();

        CreateOrderRequest order = new CreateOrderRequest();
        order.setAppid(properties.getAppId());
        order.setTransactionId(transactionId);
        order.setOutOrderNo(outOrderNo);

        //接收方
        List<CreateOrderReceiver> receivers = new ArrayList<>();
        CreateOrderReceiver receiver = new CreateOrderReceiver();
        receiver.setAccount(openId);
        receiver.setType(ReceiverType.PERSONAL_OPENID.name());


        //分账金额 amount - 转成分
        //amount.multiply(new BigDecimal(100))
        receiver.setAmount(1L);
        receiver.setDescription("给司机分账1分钱");

        receivers.add(receiver);
        order.setReceivers(receivers);

        order.setUnfreezeUnsplit(true);
        //分成成功后的回调
        order.setNotifyUrl(properties.getShardingNotifyUrl());

        OrdersEntity ordersEntity = profitsharingService.createOrder(order);
        OrderStatus state = ordersEntity.getState();
        log.info("分账结果 {} = {}",ordersEntity,state);
        return state == OrderStatus.FINISHED;



    }

    public boolean querySharding(String outOrderNo,String transactionId){
        //延迟10s中
        ProfitsharingService profitsharingService = new ProfitsharingService.Builder().config(config).build();
        QueryOrderRequest query = new QueryOrderRequest();
        query.setOutOrderNo(outOrderNo);
        query.setTransactionId(transactionId);
        OrdersEntity ordersEntity = profitsharingService.queryOrder(query);
        OrderStatus state = ordersEntity.getState();
        log.info("分账结果 {} = {}",ordersEntity,state);
        return state == OrderStatus.FINISHED;
    }

}
